/**
 * 网络请求工具类
 * 适配 UniApp 微信小程序，支持请求拦截、响应处理、错误提示
 */
const baseUrl = 'https://api.example.com'; // 后端接口基础地址（根据实际项目修改）

/**
 * 请求拦截器
 * @param {Object} options - 原始请求参数
 * @returns {Object} 处理后的请求参数
 */
const requestInterceptor = (options) => {
  // 1. 添加基础地址（如果请求url不是完整路径）
  if (!options.url.startsWith('http')) {
    options.url = baseUrl + options.url;
  }

  // 2. 设置默认请求头
  options.header = {
    'Content-Type': 'application/json', // 默认JSON格式
    ...options.header, // 允许覆盖默认头
  };

  // 3. 添加Token（如果存在本地存储的登录凭证）
  const token = uni.getStorageSync('userToken');
  if (token) {
    options.header.Authorization = `Bearer ${token}`;
  }

  // 4. 设置默认超时时间（15秒）
  options.timeout = options.timeout || 15000;

  return options;
};

/**
 * 响应拦截器
 * @param {Object} response - 原始响应数据
 * @param {Object} options - 本次请求参数
 * @returns {Promise} 处理后的响应数据或错误
 */
const responseInterceptor = (response, options) => {
  const { statusCode, data } = response;

  // 1. 网络层面成功（200 <= statusCode < 300）
  if (statusCode >= 200 && statusCode < 300) {
    // 2. 业务层面成功（假设后端约定 code=0 为成功）
    if (data.code === 0) {
      return Promise.resolve(data.data); // 返回业务数据
    }

    // 3. 业务层面失败（如参数错误、权限不足等）
    const errorMsg = data.message || '操作失败，请重试';
    // 非静默请求才显示错误提示（允许通过 options.silent 控制）
    if (!options.silent) {
      uni.showToast({
        title: errorMsg,
        icon: 'none',
        duration: 2000,
      });
    }
    return Promise.reject(new Error(errorMsg));
  }

  // 4. 网络层面失败（如404、500等）
  let errorMsg = '网络异常，请稍后再试';
  switch (statusCode) {
    case 401:
      errorMsg = '登录已过期，请重新登录';
      // 自动跳转到登录页（排除登录接口本身，避免死循环）
      if (!options.url.includes('/auth/login')) {
        uni.navigateTo({ url: '/pages/login/login' });
      }
      break;
    case 403:
      errorMsg = '没有权限执行此操作';
      break;
    case 404:
      errorMsg = '请求的资源不存在';
      break;
    case 500:
      errorMsg = '服务器内部错误，请稍后再试';
      break;
    default:
      errorMsg = `请求失败（${statusCode}）`;
  }

  if (!options.silent) {
    uni.showToast({
      title: errorMsg,
      icon: 'none',
      duration: 2000,
    });
  }
  return Promise.reject(new Error(errorMsg));
};

/**
 * 统一请求方法
 * @param {Object} options - 请求参数
 * @returns {Promise} 请求结果
 */
const request = (options) => {
  // 1. 处理请求参数（合并默认配置）
  const requestOptions = {
    method: 'GET', // 默认GET方法
    ...options,
  };

  // 2. 请求拦截处理
  const processedOptions = requestInterceptor(requestOptions);

  // 3. 发起请求
  return new Promise((resolve, reject) => {
    uni.request({
      ...processedOptions,
      success: (response) => {
        // 响应拦截处理
        responseInterceptor(response, processedOptions)
          .then(resolve)
          .catch(reject);
      },
      fail: (err) => {
        // 网络错误（如断网、超时）
        const errorMsg = err.errMsg || '请求失败，请检查网络';
        if (!processedOptions.silent) {
          uni.showToast({
            title: errorMsg,
            icon: 'none',
            duration: 2000,
          });
        }
        reject(new Error(errorMsg));
      },
    });
  });
};

/**
 * 快捷请求方法封装
 */
const http = {
  // GET请求
  get(url, data = {}, options = {}) {
    return request({
      url,
      data,
      method: 'GET',
      ...options,
    });
  },

  // POST请求
  post(url, data = {}, options = {}) {
    return request({
      url,
      data,
      method: 'POST',
      ...options,
    });
  },

  // PUT请求（更新资源）
  put(url, data = {}, options = {}) {
    return request({
      url,
      data,
      method: 'PUT',
      ...options,
    });
  },

  // DELETE请求（删除资源）
  delete(url, data = {}, options = {}) {
    return request({
      url,
      data,
      method: 'DELETE',
      ...options,
    });
  },
};

export default http;